package pe.edu.pucp.Seguridad.DAO;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import pe.edu.pucp.Modelo.Elemento;
import pe.edu.pucp.Modelo.EstadoPerfil;
import pe.edu.pucp.Modelo.Perfil;
import pe.edu.pucp.Modelo.Permiso;
import pe.edu.pucp.Util.HibernateUtil;

public class PerfilDAO {
     
    public Perfil guardarPerfil(Perfil p){        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  null;         
        try{
            tx =  session.beginTransaction();         
            session.saveOrUpdate(p);                        
            tx.commit();
        }catch(Exception e) {
            if (tx!=null) tx.rollback();
        } finally {
            session.close();            
            return p;
        }
    }
  
    public boolean existeNombrePerfil(String perfil,int idperfil){
        boolean existe;
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        Query query = session.createQuery("from Perfil where descripcion = :per and idperfil<>:id");            
        query.setString("per", perfil);
        query.setInteger("id", idperfil);
        List lista = query.list();
        Iterator iter = lista.iterator();
        existe =iter.hasNext();                            
        tx.commit();

        session.close();
        return existe;
     
    }      
    
    public boolean existeNombrePerfil(String perfil){
        boolean existe;
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        Query query = session.createQuery("from Perfil where descripcion = :per");            
        query.setString("per", perfil);
        List lista = query.list();
        Iterator iter = lista.iterator();
        existe =iter.hasNext();                            
        tx.commit();

        session.close();
        return existe;
     
    }     
    
    public Perfil modificarPerfil(Perfil p){        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();         
        session.update(p);                        
        tx.commit();

        session.close();            
        return p;
        
    }
    
    public void agregarPermiso(int pf, int el, int ac){        
        Permiso per = new Permiso();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();         

        Permiso pr = buscarPermiso(pf,el);
        if (pr!=null){
            pr.setPermiso(ac);
            session.update(pr);   
        }
        else{
            per.setPerfil(buscarPerfil(pf));
            per.setElemento(buscarElemento(el));
            per.setPermiso(ac);
            session.save(per);                                                                                             
        }

        tx.commit();
        session.close();                        
  
    }    

    public Permiso buscarPermiso(int idperfil, int idelemento){
        Permiso a = null;
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        Query query = session.createQuery("from Permiso where idperfil = :idp and idelemento = :ide ");
        query.setInteger("idp", idperfil);
        query.setInteger("ide", idelemento);
        List lista = query.list();
        Iterator iter = lista.iterator();
        if (iter.hasNext()) {    
            a = (Permiso) iter.next();                    
        }        
        tx.commit();

        session.close();
        return a;

    }       
    
    public Elemento buscarElemento(int idelemento){
        Elemento a = new Elemento();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        Query query = session.createQuery("from Elemento where idelemento = :id ");
        query.setInteger("id", idelemento);
        List lista = query.list();
        Iterator iter = lista.iterator();
        if (iter.hasNext()) {    
            a = (Elemento) iter.next();                    
        }        
        tx.commit();

        session.close();
        return a;

    }    
    
    public Perfil buscarPerfil(int idperfil){
        Perfil a = new Perfil();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        Query query = session.createQuery("from Perfil where idperfil = :id ");
        query.setInteger("id", idperfil);
        List lista = query.list();
        Iterator iter = lista.iterator();
        if (iter.hasNext()) {    
            a = (Perfil) iter.next();   
            Hibernate.initialize(a.getPermisos());            
            Hibernate.initialize(a.getUsuarios());            
            Hibernate.initialize(a.getEstadoPerfil());                  
        }        
        tx.commit();

        session.close();
        return a;

    }     
    
    public ArrayList<EstadoPerfil> listarEstado(){
        ArrayList<EstadoPerfil> listaEstado = new ArrayList<>();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        List lista = session.createQuery("from EstadoPerfil order by idestado").list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            EstadoPerfil a = (EstadoPerfil) iter.next();
            listaEstado.add(a);
        }
        
        tx.commit();
        session.close();

        return listaEstado;
    }     
 
    public EstadoPerfil buscarEstado(int idestado){
        EstadoPerfil a = new EstadoPerfil();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        Query query = session.createQuery("from EstadoPerfil where idestado = :id");
        query.setInteger("id", idestado);
        List lista = query.list();
        Iterator iter = lista.iterator();
        if (iter.hasNext()) {    
            a = (EstadoPerfil) iter.next();        
        }

        tx.commit();

        session.close();
        return a;
     
    }     

    public ArrayList<Perfil> listarPerfil(int estd, String nombre){
        ArrayList<Perfil> listaResultados = new ArrayList<>();
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        String q = "select p from Perfil p where upper(p.descripcion) like '%'||:nomb||'%' ";        
        if (estd>0){ q+= "and p.estadoPerfil.idestado = :estd order by idperfil"; }
        Query query = session.createQuery(q);
        query.setString("nomb", nombre);
        if (estd>0){ query.setInteger("estd", estd); } 
        
        List lista = query.list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Perfil p = (Perfil) iter.next();
            Hibernate.initialize(p.getPermisos());            
            Hibernate.initialize(p.getUsuarios());            
            Hibernate.initialize(p.getEstadoPerfil());            
            listaResultados.add(p);
        }
        
        tx.commit();
        session.close();
        
        return listaResultados;
    }    
    
    public ArrayList<Perfil> listarPerfil(){
        ArrayList<Perfil> listaResultados = new ArrayList<>();
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        List lista = session.createQuery("from Perfil order by idperfil").list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Perfil p = (Perfil) iter.next();
            Hibernate.initialize(p.getPermisos());            
            Hibernate.initialize(p.getUsuarios());            
            Hibernate.initialize(p.getEstadoPerfil());            
            listaResultados.add(p);
        }
        
        tx.commit();
        session.close();
        
        return listaResultados;
    }
}
